#include <stdint.h>
#include <common.h>
#include "macro.h"
#include <math.h>

#define GROUPNUM 16
#define BLOCKSIZE 4
#define BLOCKNUM  1

uint64_t ICACHE_MISS = 0;

typedef struct cacheblock {
  word_t tag;
  word_t valid;
  // uint32_t blocks[BLOCKSIZE/4];
} cacheblock;

static cacheblock icache[GROUPNUM][BLOCKNUM];

double log2(double a) {
  return log(a)/log(2);
}

static word_t m;
static word_t n;
static word_t line;

void init_icache() {
  for (int i = 0; i < GROUPNUM; i++) {
    for (int j = 0; j < BLOCKNUM; j ++) {
      icache[i][j].tag   = 0;
      icache[i][j].valid = 0;
    }
  }

  m = (word_t)log2(BLOCKSIZE);
  n = (word_t)log2(GROUPNUM);
  line = sizeof(word_t) * 8 - m - n + BLOCKSIZE * 8 + 1;
}

void icache_read(word_t pc) {
  word_t index = BITS(pc, m+n-1, m);
  word_t atag  = BITS(pc, sizeof(word_t)*8-1, m+n);

  if (!(icache[index][0].valid == 1 && icache[index][0].tag == atag)) {
    icache[index][0].valid = 1;
    icache[index][0].tag   = atag;

    ICACHE_MISS ++;
  }
}
